package com.juqimiao.raccoon.commodity.command;

import com.juqimiao.linn.command.CommandExecutor;
import com.juqimiao.linn.command.CommandExecutorI;
import com.juqimiao.linn.exception.BusinessException;
import com.juqimiao.linn.exception.SystemException;
import com.juqimiao.linn.extension.ExtensionExecutor;
import com.juqimiao.linn.transfer.Response;
import com.juqimiao.linn.transfer.query.builders.ResponseBuilder;
import com.juqimiao.raccoon.commodity.constraints.OperationUpdateGroup;
import com.juqimiao.raccoon.commodity.domain.CategoryGroupFactory;
import com.juqimiao.raccoon.commodity.domain.category.CategoryGroup;
import com.juqimiao.raccoon.commodity.dto.UpdateCategoryGroupCmd;
import com.juqimiao.raccoon.commodity.extension.CategoryGroupValidExtPt;
import com.juqimiao.raccoon.commodity.repository.CategoryGroupRepository;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.List;

@CommandExecutor
public class UpdateCategoryGroupCmdExt implements CommandExecutorI<Response, UpdateCategoryGroupCmd> {

    private CategoryGroupRepository repository;
    private ExtensionExecutor extensionExecutor;
    private CategoryGroupFactory factory;

    @Autowired
    public UpdateCategoryGroupCmdExt(CategoryGroupRepository repository,
                                     ExtensionExecutor extensionExecutor,
                                     CategoryGroupFactory factory) {
        this.repository = repository;
        this.extensionExecutor = extensionExecutor;
        this.factory = factory;
    }

    @Override
    public Response execute(UpdateCategoryGroupCmd cmd) {

        //Data Validation
        extensionExecutor.executeVoid(CategoryGroupValidExtPt.class,
                extension -> extension.validate(cmd.getCategoryGroupAO(), OperationUpdateGroup.class));

        /* Restore the CategoryGroup */
        CategoryGroup categoryGroup = factory.create(repository, cmd.getCategoryGroupAO().getId());

        //check batchUpdate policy, check the categoryGroup status,
        if (!categoryGroup.getPolicy().canUpdate()) {
            throw new BusinessException(String.format("The Group %s cannot be updated ", categoryGroup.getName()));
        }

        /* batchUpdate the CategoryGroup */
        categoryGroup.setName(cmd.getCategoryGroupAO().getName());
        categoryGroup.setSpell(cmd.getCategoryGroupAO().getSpell());
        categoryGroup.setScenario(cmd.getCategoryGroupAO().getScenario());
        categoryGroup.setGroupType(cmd.getCategoryGroupAO().getGroupType());
        categoryGroup.setSubmitId(cmd.getCategoryGroupAO().getSubmitId());
        categoryGroup.setAuthorized(cmd.getCategoryGroupAO().getAuthorized());
        categoryGroup.setStatus(cmd.getCategoryGroupAO().getStatus());
        /* check whether or not  the name is exist. */
        if (categoryGroup.getPolicy().hasSameName()) {
            throw new BusinessException("The Name cannot be same in CategoryType= "
                    + categoryGroup.getGroupType()
                    + " and Scenario= "
                    + categoryGroup.getScenario());
        }

        List<CategoryGroup> groups = new ArrayList<>();
        groups.add(categoryGroup);
        /* persist the categoryGroup */
        if (repository.batchUpdate(groups) < 0) {
            throw new SystemException("The Name cannot be same in CategoryType= "
                    + cmd.getCategoryGroupAO().getGroupType()
                    + " and Scenario= "
                    + cmd.getCategoryGroupAO().getScenario());
        }

        return ResponseBuilder.builder().success(String.format("类目分组 %s 更新成功", categoryGroup.getName())).build();
    }
}
